<?php
/**
 * SSL 추상화 클래스
 *
 * 해당 라이브러리는 직접 호출하는것을 권장하지 않습니다.
 * 코어에서 제공하는 공개 인터페이스를 사용해주시기 바랍니다.
 *
 * @author Platform Team
 */

abstract class utilSslwrapAbstract
{
    /**
     * CURL 타임아웃(초)
     * @var int
     */
    private static $iCurlTimeout = 5;

    /**
     * 실패코드 상수 반환 - CURL 관련 에러시
     *
     * @return int
     */
    final protected static function _getCurlFailCode()
    {
        return 1;
    }

    /**
     * 실패코드 상수 반환 - API 관련 에러시
     *
     * @return int
     */
    final protected static function _getApiFailCode()
    {
        return 2;
    }

    /**
     * 실패코드 상수 반환 - 내부 로직 수행에 따른 에러시
     *
     * @return int
     */
    final protected static function _getSelfFailCode()
    {
        return 3;
    }

    /**
     * ENCRYPT 데이터 변환
     *
     * @param mixed $mData
     * @return string
     */
    protected static function _convEncrypt($mData)
    {
        if (FW_CHARSET != 'utf-8') {
            $sResult = serialize(iconvDeep($mData, FW_CHARSET, 'utf-8'));
        } else {
            $sResult = serialize($mData);
        }

        return $sResult;
    }

    /**
     * DECRYPT 데이터 변환
     *
     * @param string $sData
     * @return mixed
     */
    protected static function _convDecrypt($sData)
    {
        if (FW_CHARSET != 'utf-8') {
            $mResult = iconvDeep(unserialize($sData), 'utf-8', FW_CHARSET);
        } else {
            $mResult = unserialize($sData);
        }

        return $mResult;
    }

    /**
     * API 결과 데이터 반환
     *
     * @param mixed $mResponse
     * @return utilSslwrapException | string
     */
    protected static function _result($mResponse)
    {
        if (is_array($mResponse) === true) {
            return new utilSslwrapException(self::_getCurlFailCode(), $mResponse['ssl_err_msg']);
        }

        if (preg_match('/^ERROR[\s]*:[\s]*(.+)$/', $mResponse, $aMatch) !== 0) {
            return new utilSslwrapException(self::_getApiFailCode(), $aMatch[1]);
        }

        return $mResponse;
    }

    /**
     * CURL 통신
     *
     * @param string $sUrl
     * @param mixed $mData
     * @return string(성공) | array(실패)
     *
     * 실패시
     * array(
     *     'ssl_err_msg' => 에러메세지,
     *     'ssl_err_no' => 에러넘버
     * )
     */
    protected static function _curl($sUrl, $mData)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $sUrl);
        curl_setopt($ch, CURLOPT_TIMEOUT, self::$iCurlTimeout);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$iCurlTimeout);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $mData);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        $sResponse = curl_exec($ch);
        $iErrNo = curl_errno($ch);
        $sErrMsg = curl_error($ch);

        curl_close($ch);

        if ($iErrNo !== CURLE_OK) {
            return array(
                'ssl_err_msg' => $sErrMsg,
                'ssl_err_no' => $iErrNo
            );
        }

        return $sResponse;
    }

    /**
     * HASH 생성
     *
     * @param string $sUrl
     * @param string $sPasswd
     * @param string $sPath
     * @return utilSslwrapException | true
     */
    protected static function _createHash($sUrl, $sPasswd, $sPath)
    {
        $aParam = array(
            'method' => 'createKey',
            'p' => $sPasswd
        );

        $mResponse = self::_curl($sUrl, $aParam);
        $mResult = self::_result($mResponse);

        if (is_object($mResult) === true) {
            return $mResult;
        }

        $Return = json_decode($mResult);

        if ($Return->returnCode !== '0000') {
            return new utilSslwrapException(self::_getApiFailCode(), $Return->returnMSG);
        }

        $r = @file_put_contents($sPath, 'key=' . $Return->returnMSG);

        if ($r === false) {
            return new utilSslwrapException(self::_getSelfFailCode(), 'Can not create a hash file - path :' . $sPath . '; return : ' . $Return->returnMSG);
        }

        return true;
    }

    /**
     * HASH 갱신
     *
     * @param string $sUrl
     * @param string $sPasswd
     * @param string $sPath
     * @return utilSslwrapException | true
     */
    protected static function _refreshHash($sUrl, $sPasswd, $sPath)
    {
        $aParam = array(
            'method' => 'refreshKey',
            'p' => $sPasswd
        );

        $mResponse = self::_curl($sUrl, $aParam);
        $mResult = self::_result($mResponse);

        if (is_object($mResult) === true) {
            return $mResult;
        }

        $Return = json_decode($mResult);

        if ($Return->returnCode !== '0000') {
            return new utilSslwrapException(self::_getApiFailCode(), $Return->returnMSG);
        }

        $r = @file_put_contents($sPath, 'key=' . $Return->returnMSG);

        if ($r === false) {
            return new utilSslwrapException(self::_getSelfFailCode(), 'Can not refresh a hash file - path : ' . $sPath . '; return : ' . $Return->returnMSG);
        }

        return true;
    }

    /**
     * HASH 만료
     *
     * @param string $sUrl
     * @param string $sPasswd
     * @param string $sPath
     * @return utilSslwrapException | true
     */
    protected static function _expireHash($sUrl, $sPasswd, $sPath)
    {
        $aParam = array(
            'method' => 'expireKey',
            'p' => $sPasswd
        );

        $mResponse = self::_curl($sUrl, $aParam);
        $mResult = self::_result($mResponse);

        if (is_object($mResult) === true) {
            return $mResult;
        }

        $Return = json_decode($mResult);

        if ($Return->returnCode !== '0000') {
            return new utilSslwrapException(self::_getApiFailCode(), $Return->returnMSG);
        }

        @unlink($sPath);

        return true;
    }

    /**
     * HASH 키 반환
     *
     * @param string $sPath (HASH 참조 파일 경로)
     * @return string | false
     */
    public static function readHash($sPath)
    {
        if (is_file($sPath) === false) {
            return false;
        }

        $sSource = file_get_contents($sPath);

        $sHash = preg_replace('/[\s]*key[\s]*=[\s]*(.+)/', '$1', $sSource);
        $sHash = trim($sHash);

        return strlen($sHash) === 32 ? $sHash : false;
    }
}
